#include "SingleYH.h"
#include "../Program.h"
#include "../Util/Util.h"
#include "../Util/Timer.h"

SingleYH::SingleYH() {};

SingleYH::~SingleYH() {};

void SingleYH::SetSaveImgPatch(std::string patch)
{
    ImgSavePath = patch;
}

void SingleYH::SetLoadImgPatch(std::string patch)
{
    ImgPatch = patch;
}

void SingleYH::Run(int32 yysPID, bool SaveImg)
{
    OpenCVTools* OpenCvMachine = new OpenCVTools();
    if (!OpenCvMachine)
    {
        cout << "初始化OpenCVTool模块失败!" << endl;
        return;
    }

    HWND hwnd = OpenCvMachine->GetHwndByPid(yysPID);
    if (!hwnd)
    {
        cout << "获取窗口句柄失败" << endl;
        cin.get();
        return;
    }

    // 模板加载结果。加载失败则进入截图模式
    bool LoadTemplate = true;

    Mat 主界面_御魂按钮 = imread(ImgPatch + "mian-button-yuhun.png", IMREAD_GRAYSCALE);
    Mat 战斗界面_通用_返回 = imread(ImgPatch + "yuhun-ui-button-return.png", IMREAD_GRAYSCALE);
    Mat 战斗界面_按钮_妖术 = imread(ImgPatch + "yuhun-attack-button-yaoshu.png", IMREAD_GRAYSCALE);
    Mat 战斗界面_按钮_自动 = imread(ImgPatch + "yuhun-attack-button-zidong.png", IMREAD_GRAYSCALE);
    Mat 战斗准备界面_按钮_预设 = imread(ImgPatch + "yuhun-attack-button-yushe.png", IMREAD_GRAYSCALE);
    Mat 战斗准备界面_按钮_准备 = imread(ImgPatch + "yuhun-attack-button-zhunbei.png", IMREAD_GRAYSCALE);
    Mat 战斗胜利界面_锦囊 = imread(ImgPatch + "yuhun-ui-button-jiesuan.png", IMREAD_GRAYSCALE);
    Mat 战斗胜利界面_写轮眼鼓 = imread(ImgPatch + "yuhun-ui-button-shengli.png", IMREAD_GRAYSCALE);
    Mat 战斗胜利界面_胜利字样 = imread(ImgPatch + "yuhun-ui-button-shengli-zi.png", IMREAD_GRAYSCALE);
    Mat 战斗失败界面_坏写轮眼鼓 = imread(ImgPatch + "yuhun-ui-button-shibai.png", IMREAD_GRAYSCALE);
    Mat 战斗失败界面_再次挑战字样 = imread(ImgPatch + "yuhun-ui-button-shibai-zaicitiaozhan.png", IMREAD_GRAYSCALE);
    Mat 御魂玩法界面_按钮_八岐大蛇 = imread(ImgPatch + "yuhun-ui-button-target.png", IMREAD_GRAYSCALE);
    Mat 御魂界面_按钮_挑战 = imread(ImgPatch + "yuhun-ui-button-tiaozhan.png", IMREAD_GRAYSCALE);
    Mat 御魂界面_按钮_确定 = imread(ImgPatch + "yuhun-ui-button-ok.png", IMREAD_GRAYSCALE);
    Mat 御魂界面_按钮_组队 = imread(ImgPatch + "yuhun-ui-button-group.png", IMREAD_GRAYSCALE);

    if (主界面_御魂按钮.empty() ||
        战斗界面_通用_返回.empty() ||
        战斗界面_按钮_妖术.empty() ||
        战斗界面_按钮_自动.empty() ||
        战斗准备界面_按钮_预设.empty() ||
        战斗准备界面_按钮_准备.empty() ||
        战斗胜利界面_锦囊.empty() ||
        战斗胜利界面_写轮眼鼓.empty() ||
        战斗胜利界面_胜利字样.empty() ||
        战斗失败界面_坏写轮眼鼓.empty() ||
        战斗失败界面_再次挑战字样.empty() ||
        御魂玩法界面_按钮_八岐大蛇.empty() ||
        御魂界面_按钮_挑战.empty() ||
        御魂界面_按钮_确定.empty() ||
        御魂界面_按钮_组队.empty())
    {
        cout << "加载模板失败" << endl;
        //cin.get();
        //return 0;

        LoadTemplate = false;
    }
    else
    {
        cout << GetNowTimeStr() << "加载模板成功,等待进入「探索」界面" << endl;
    }

    // 注册Mat模板
    OpenCvMachine->RegisterMatchMatTemplate((int)NowState::NOWSTATE_MAIN_TANSUO, 主界面_御魂按钮, 0.8, (int)NowState::NOWSTATE_YUHUN_SWITCH);
    OpenCvMachine->RegisterMatchMatMouseClick((int)NowState::NOWSTATE_MAIN_TANSUO, 主界面_御魂按钮, 0.8);

    OpenCvMachine->RegisterMatchMatTemplate((int)NowState::NOWSTATE_YUHUN_SWITCH, 御魂玩法界面_按钮_八岐大蛇, 0.8, (int)NowState::NOWSTATE_YUHUN_TYPE);
    OpenCvMachine->RegisterMatchMatMouseClick((int)NowState::NOWSTATE_YUHUN_SWITCH, 御魂玩法界面_按钮_八岐大蛇, 0.8);

    OpenCvMachine->RegisterMatchMatTemplate((int)NowState::NOWSTATE_YUHUN_TYPE, 御魂界面_按钮_挑战, 0.8, (int)NowState::NOWSTATE_YUHUN_ATTACK_ZHUNBEI);
    OpenCvMachine->RegisterMatchMatTemplate((int)NowState::NOWSTATE_YUHUN_TYPE, 御魂界面_按钮_组队, 0.8, (int)NowState::NOWSTATE_YUHUN_ATTACK_ZHUNBEI);
    OpenCvMachine->RegisterMatchMatMouseClick((int)NowState::NOWSTATE_YUHUN_TYPE, 御魂界面_按钮_挑战, 0.8);

    OpenCvMachine->RegisterMatchMatTemplate((int)NowState::NOWSTATE_YUHUN_ATTACK_ZHUNBEI, 战斗准备界面_按钮_预设, 0.8, (int)NowState::NOWSTATE_YUHUN_ATTACK);
    OpenCvMachine->RegisterMatchMatTemplate((int)NowState::NOWSTATE_YUHUN_ATTACK_ZHUNBEI, 战斗准备界面_按钮_准备, 0.8, (int)NowState::NOWSTATE_YUHUN_ATTACK);
    OpenCvMachine->RegisterMatchMatMouseClick((int)NowState::NOWSTATE_YUHUN_ATTACK_ZHUNBEI, 战斗准备界面_按钮_准备, 0.8);

    OpenCvMachine->RegisterMatchMatTemplate((int)NowState::NOWSTATE_YUHUN_ATTACK, 战斗界面_通用_返回, 0.8, (int)NowState::NOWSTATE_YUHUN_JIESUAN_CONDITION);
    OpenCvMachine->RegisterMatchMatTemplate((int)NowState::NOWSTATE_YUHUN_ATTACK, 战斗界面_按钮_妖术, 0.8, (int)NowState::NOWSTATE_YUHUN_JIESUAN_CONDITION);
    OpenCvMachine->RegisterMatchMatTemplate((int)NowState::NOWSTATE_YUHUN_ATTACK, 战斗界面_按钮_自动, 0.8, (int)NowState::NOWSTATE_YUHUN_JIESUAN_CONDITION);

    OpenCvMachine->RegisterConditionMatchMatTemplate((int)NowState::NOWSTATE_YUHUN_JIESUAN_CONDITION, 战斗胜利界面_锦囊, 0.8, (int)NowState::NOWSTATE_YUHUN_JIESUAN_Win);
    OpenCvMachine->RegisterConditionMatchMatTemplate((int)NowState::NOWSTATE_YUHUN_JIESUAN_CONDITION, 战斗胜利界面_写轮眼鼓, 0.8, (int)NowState::NOWSTATE_YUHUN_JIESUAN_Win);
    OpenCvMachine->RegisterConditionMatchMatTemplate((int)NowState::NOWSTATE_YUHUN_JIESUAN_CONDITION, 战斗胜利界面_胜利字样, 0.8, (int)NowState::NOWSTATE_YUHUN_JIESUAN_Win);
    OpenCvMachine->RegisterConditionMatchMatTemplate((int)NowState::NOWSTATE_YUHUN_JIESUAN_CONDITION, 战斗失败界面_坏写轮眼鼓, 0.8, (int)NowState::NOWSTATE_YUHUN_JIESUAN_Lower);
    OpenCvMachine->RegisterConditionMatchMatTemplate((int)NowState::NOWSTATE_YUHUN_JIESUAN_CONDITION, 战斗失败界面_再次挑战字样, 0.8, (int)NowState::NOWSTATE_YUHUN_JIESUAN_Lower);

    OpenCvMachine->RegisterMatchMatTemplate((int)NowState::NOWSTATE_YUHUN_JIESUAN_Win, 战斗胜利界面_锦囊, 0.8, (int)NowState::NOWSTATE_YUHUN_TYPE);
    OpenCvMachine->RegisterMatchMatTemplate((int)NowState::NOWSTATE_YUHUN_JIESUAN_Lower, 战斗失败界面_坏写轮眼鼓, 0.8, (int)NowState::NOWSTATE_YUHUN_TYPE);
    OpenCvMachine->RegisterMatchMatTemplate((int)NowState::NOWSTATE_YUHUN_JIESUAN_Lower, 战斗失败界面_再次挑战字样, 0.8, (int)NowState::NOWSTATE_YUHUN_TYPE);
    OpenCvMachine->RegisterMatchMatMouseClick((int)NowState::NOWSTATE_YUHUN_JIESUAN_Win, 战斗胜利界面_锦囊, 0.8);
    OpenCvMachine->RegisterMatchMatMouseClick((int)NowState::NOWSTATE_YUHUN_JIESUAN_Lower, 战斗失败界面_坏写轮眼鼓, 0.8);

    uint64_t UpdatePrevTimeDiff = getMSTime();
    uint32_t UpdateDiffTime = 1 * IN_MILLISECONDS;

    NowState now_state = NowState::NOWSTATE_MAIN_TANSUO;
    uint64_t now_stop_time = 30 * MINUTE * IN_MILLISECONDS;// 本次休息时长
    uint64_t now_run_time = 120 * MINUTE * IN_MILLISECONDS;// 本次执行时长
    bool stop_notify = true;// 是否发送休息公告
    int next_changeState = -1;//下一次检测失败切换的状态（为防止检测成功之后点击按钮失败导致状态切换到下一个阶段无限循环。发送点击按钮成功之后检测失败才切换状态）
    uint32_t checkcount = 0;// 当前检测次数（计次超过X次则走修正当前状态流程）

    while (true)
    {
        uint64_t UpdatePrivateTimeDiff = getMSTime();

        if (getMSTimeDiff(UpdatePrevTimeDiff, UpdatePrivateTimeDiff) < UpdateDiffTime)
        {
            std::this_thread::sleep_for(std::chrono::milliseconds(1));
            continue;
        }
        UpdatePrevTimeDiff = UpdatePrivateTimeDiff;

        Mat src = OpenCvMachine->hwnd2mat(hwnd);
        if (src.empty())
        {
            cout << GetNowTimeStr() << "后台截屏失败,请不要最小化目标窗口！！！！！！" << endl;
            continue;
        }

        if (now_run_time <= 0)
        {
            // 战斗状态不进入休息，因为战斗会结束。结束了步骤就不对了。
            if (now_state != NowState::NOWSTATE_YUHUN_ATTACK && now_state != NowState::NOWSTATE_YUHUN_ATTACK_ZHUNBEI)
            {
                // 进入休息状态
                if (now_stop_time > 0)
                {
                    if (stop_notify)
                    {
                        cout << GetNowTimeStr() << "当前处于休息时间,下次执行开始于：" << now_stop_time / (MINUTE * IN_MILLISECONDS) << "分钟后" << endl;
                        stop_notify = false;
                    }
                    now_stop_time -= UpdateDiffTime;
                    continue;
                }
                else
                {
                    // 休息结束重置时间
                    now_run_time = (uint64_t)irand(80, 140) * MINUTE * IN_MILLISECONDS;
                    now_stop_time = (uint64_t)irand(20, 40) * MINUTE * IN_MILLISECONDS;
                    cout << GetNowTimeStr() << "重置战斗时间,本次执行时长：" << now_run_time / (MINUTE * IN_MILLISECONDS) << "分钟" << endl;
                    stop_notify = true;
                }
            }
        }
        else
        {
            now_run_time -= UpdateDiffTime;
        }

        if (SaveImg)
        {
            std::string fileName = ImgSavePath + "/Screen-" + std::to_string(yysPID) + "-" + to_string(time(nullptr)) + to_string(getMillisecond()) + ".png";
            imwrite(fileName.c_str(), src);
        }

        if (!LoadTemplate)
        {
            continue;
        }

        //调整大小
        //Mat monitor;
        //resize(src, monitor, Size(240, 140));
        //imshow("monitor", monitor);
        //imshow("output", src);

        //图像灰度
        cvtColor(src, src, COLOR_BGR2GRAY);

        if (next_changeState >= 0)
        {
            cout << "当前状态:" << (int)now_state << "切换为:" << next_changeState << endl;
            now_state = (NowState)next_changeState;
            next_changeState = -1;
        }

        int matchResoult = -1;

        switch (now_state)
        {
        case NowState::NOWSTATE_MAIN_TANSUO:
        case NowState::NOWSTATE_YUHUN_SWITCH:
        case NowState::NOWSTATE_YUHUN_TYPE:
        case NowState::NOWSTATE_YUHUN_ATTACK_ZHUNBEI:
        case NowState::NOWSTATE_YUHUN_ATTACK:
        case NowState::NOWSTATE_YUHUN_JIESUAN_Win:
        case NowState::NOWSTATE_YUHUN_JIESUAN_Lower:
            matchResoult = OpenCvMachine->MatchTemplateFromState((int)now_state, src);
            if (matchResoult != -1)
            {
                Sleep(irand(1000, 2500));

                if (OpenCvMachine->MouseClickFromMatchTemplateState((int)now_state, src))
                {
                    //cout << "当前状态:" << (int)now_state << "返回状态:" << matchResoult << endl;
                    //now_state = (NowState)matchResoult;
                    next_changeState = matchResoult;
                }
            }
            break;
        case NowState::NOWSTATE_YUHUN_JIESUAN_CONDITION:
            matchResoult = OpenCvMachine->MatchTemplateConditionFromState((int)now_state, src);
            if (matchResoult != -1)
            {
                Sleep(irand(1000, 2500));

                if (OpenCvMachine->MouseClickFromMatchTemplateState((int)now_state, src))
                {
                    //cout << "当前状态:" << (int)now_state << "返回状态:" << matchResoult << endl;
                    //now_state = NowState::NOWSTATE_YUHUN_TYPE;
                    next_changeState = matchResoult;
                }
            }
            break;
        default:
            break;
        }

        cv::waitKey(UpdateDiffTime);
    }
}
